package com.aabte.lock.jedis.v3;

import com.aabte.lock.jedis.Constant;
import com.aabte.lock.jedis.v1.RedisPessimisticLockTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class RedisTransactionProcessTest {

    private JedisPool jedisPool;

    @Before
    public void before() throws IOException {

        InputStream in = RedisPessimisticLockTest.class.getClassLoader().getResourceAsStream("redis.properties");
        Properties properties = new Properties();
        properties.load(in);

        String host = properties.getProperty(Constant.JedisConstant.REDIS_HOST);
        int port = Integer.parseInt(properties.getProperty(Constant.JedisConstant.REDIS_PORT));
        int maxTotal = Integer.parseInt(properties.getProperty(Constant.JedisConstant.REDIS_MAX_TOTAL));
        int maxIdle = Integer.parseInt(properties.getProperty(Constant.JedisConstant.REDIS_MAX_IDLE));
        int maxWaitMillis = Integer.parseInt(properties.getProperty(Constant.JedisConstant.REDIS_MAX_WAIT_MILLIS));

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMaxWaitMillis(maxWaitMillis);

        jedisPool = new JedisPool(config, host, port);
    }

    @After
    public void after(){
        jedisPool.close();
    }

    @Test
    public void test(){
        ProductRedisTransactionProcess productLockProcess = new ProductRedisTransactionProcess();
        Jedis client = jedisPool.getResource();

        String lockKey = "key_product_number";

        client.set("key_product_number", "100");

        List<Thread> threads = new ArrayList<>(105);
        for (int i = 0; i < 105; i++) {
            RedisTransaction redisTransaction = new RedisTransaction(jedisPool, lockKey, productLockProcess);
            TestThread testThread = new TestThread(redisTransaction);
            threads.add(testThread);
            testThread.start();
        }
        try {
            for (Thread thread : threads) {
                thread.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("主线程结束！");

    }

    public static class TestThread extends Thread {

        private RedisTransaction redisTransaction;

        public TestThread(RedisTransaction redisTransaction) {
            this.redisTransaction = redisTransaction;
        }

        @Override
        public void run() {
            redisTransaction.invoke();
        }
    }

}
